
package org.argouml.euncet.xuml;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import org.argouml.model.*;
import org.argouml.kernel.*;
import org.omg.uml.behavioralelements.collaborations.*;

import java.util.*;
import java.io.*;
import javax.script.*;

/**
*  http://argouml-stats.tigris.org/nonav/javadocs/javadocs-0.28/  (incomplet)
*  http://argouml-stats.tigris.org/nonav/javadocs/javadocs-0.22/     Ok
*  http://www.andromda.org/docs-3.3/jmi-uml1.4/index.html
*  http://www.mozilla.org/rhino/ScriptingJava.html  (Rhino)
*/
public class XUmlDialog extends JDialog {

	public static String scr = "";
	public static String scrResp = "";

	static ScriptEngineManager mgr = null;
	static ScriptEngine engine = null;	
	
	JTextArea ta = new JTextArea();
	JTextArea _ta2 = new JTextArea();

	public XUmlDialog()
	{
		// Singletons
		if (mgr == null)
		{
			try {
				mgr = new ScriptEngineManager();
				engine = mgr.getEngineByName("JavaScript");	

				ProjectManager _pm = ProjectManager.getManager();
				Project _p = _pm.getCurrentProject();
				org.omg.uml.modelmanagement.Model _m = (org.omg.uml.modelmanagement.Model) _p.getModel();
				_m.setName("xUMLModel");
				CollaborationsFactory _clf = Model.getCollaborationsFactory();
				Collaboration _col = (Collaboration) _clf.buildCollaboration(_m);
				_col.setName("InstancesModel");

				engine.eval("importPackage(org.argouml.uoc.xuml);");
				Bindings bnds = engine.getBindings(ScriptContext.ENGINE_SCOPE);
				bnds.put("_col", _col);
				bnds.put("_ta2", _ta2);
			} catch (Exception e) {}
		}
	
		try {
			String scriptCode = loadScript("scripts/xumlib.js");
			engine.eval(scriptCode);
		} catch (Exception e) {}
	
	
		final XUmlDialog f = this;
//		f.setModal(true);
		f.setSize(800, 600);
		f.centra();
		f.setLayout(new BorderLayout());
		JPanel p1 = new JPanel();
		p1.setLayout(new FlowLayout());
		JLabel titol = new JLabel("<html><h2>Executable UML</h2></html>");
		p1.add(titol);
		JPanel p2 = new JPanel();
		p2.setLayout(new FlowLayout());
		JButton btnOk = new JButton("Execute");
		JButton btnClear = new JButton("Clear");
		JButton btnSample0 = new JButton("Metamodel Script demo");
		JButton btnSample1 = new JButton("Model ActionSemantics Script demo");
		JButton btnSample2 = new JButton("Free button");
		p1.add(btnClear);
		p1.add(btnSample0);
		p1.add(btnSample1);
//		p1.add(btnSample2);
		
		btnOk.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)  
			{
				String res = "";
				try
				{
				    String myJSCode = ta.getText();
					res = "" + engine.eval(myJSCode).toString();
				}
				catch (NullPointerException npex){}
				catch (Exception ex)
				{
					res = "" + ex.toString();
					ex.printStackTrace();
				}
				
				if (res.trim().equals(""))
					res = "Done";
						
				scr = ta.getText();
				
				if (("" + _ta2.getText()).equals("")){
					scrResp = res;
				}else{
					scrResp = _ta2.getText() + "\n" + res;
				}

				_ta2.setText(scrResp);
			}
		});
		
		btnSample0.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)  
			{
				String scriptCode = loadScript("scripts/metamodeldemo.js");
				ta.setText(scriptCode);
			}
		});

		btnSample1.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)  
			{
				String scriptCode = loadScript("scripts/modeldemo.js");
				ta.setText(scriptCode);
			}
		});
		
		btnSample2.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)  
			{
				try {
					String scriptCode = loadScript("scripts/pending.js");
					ta.setText(scriptCode);
				} catch (Exception ex){
					ex.printStackTrace();
				}
			}
		});
		
		JButton btnCancel = new JButton("Close");
		JButton btnClearResult = new JButton("Clear result");
		p2.add(btnOk);
		p2.add(btnCancel);
		p2.add(btnClearResult);

		btnCancel.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)  
			{
//				JOptionPane.showMessageDialog(f, "Bye");
				WindowEvent windowClosingEvent = new WindowEvent(f, WindowEvent.WINDOW_CLOSING);
		        f.getToolkit().getSystemEventQueue().postEvent(windowClosingEvent);
			}
		});
		
		btnClear.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)  
			{
				scr = "";
				scrResp = "";
				ta.setText(scr);
				_ta2.setText(scrResp);
			}
		});
		
		btnClearResult.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)  
			{
				scrResp = "";
				_ta2.setText(scrResp);
			}
		});
		
		JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, new JScrollPane(ta), new JScrollPane(_ta2));
		sp.setResizeWeight(0.5);

		ta.setFont(new Font("MonoSpaced", Font.PLAIN, 12));
		_ta2.setFont(new Font("MonoSpaced", Font.PLAIN, 12));
		
		f.add(sp, BorderLayout.CENTER);
		f.add(p1, BorderLayout.NORTH);
		f.add(p2, BorderLayout.SOUTH);
		ta.requestFocus();
		
		ta.setText(scr);
		_ta2.setText(scrResp);
		ta.setCaretPosition(ta.getText().length());
	}

	public static void removeElementFromModel(Object o){
		UmlFactory uf = Model.getUmlFactory();
		uf.delete(o);
	}
	
	public void centra() {
		int anchoPantalla = getToolkit().getScreenSize().width;
		int altoPantalla = getToolkit().getScreenSize().height;

		int anchoVentana = getSize().width;
		int altoVentana = getSize().height;

		setLocation((anchoPantalla - anchoVentana) / 2,
				(altoPantalla - altoVentana) / 2);
	}
	
	public String loadScript(String filename){
		StringBuffer sb = new StringBuffer();
		try {
		    FileInputStream  f = new FileInputStream(filename);
		    byte buf[] = new byte[2048]; // buffer de 2Kb
		    int n;
		    while ((n = f.read(buf)) != -1)
		    {
				sb.append(new String(buf, 0, n));
		    } 	
		}catch(Exception e){}
		return sb.toString();
	}
	
	public static void main(String[] args) throws Exception
	{
		XUmlDialog xd = new XUmlDialog();
		xd.setVisible(true);
	}
}
